/*
 * ObjectBase.java
 * Copyright 2010 Universidad Francisco de Paula Santander (UFPS).
 * Todos los Derechos Reservados.
 * Creado el 30/11/2010, 11:15:16 AM
 */

package com.ufps.cuatro.util.base;

import com.ufps.cuatro.util.Utileria;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * <i><b>ObjectBase:</b></i>: <p>Esta Clase es la Base del Framework 4Dor. define
 * propiedades e implementaciones requeridas en todo el contexto de la aplicación.</p> 
 *
 * @author Carlos A. Torres C. - Dolly E. Guerrero. <https://code.google.com/p/tesis4dor/>
 * @version 1.0 30/11/2010
 * @see Observable
 * @see Serializable
 * @see Cloneable
 * @see Comparable<Object>
 */
public abstract class ObjectBase extends Observable implements Serializable, Comparable<Object>, Cloneable{
    private static final long serialVersionUID = -5570445403040837579L;   
    
    /**
     * Esta propiedad es utilizada para identificar el indice dentro de los archivos de
     * propiedades. Este identificador es único para cada grupo y es requerido por cada
     * objeto creado. 
     */
    protected int id;
    /**
     * Esta propiedad es utilizada para identificar el Objeto creado, muy util
     * cuando se utilizan colecciones.
     */
    protected int idClase; 
    /**
     * Esta propiedad es utilizada para identificar la posición en colecciones.
     */
    public int idColeccion;
    /**
     * Esta propiedad es utilizada para identificar el objeto.
     */
    public String uuidObj;    
    /**
     * Esta propiedad es utilizada para selecciones en contenedores gráficos.
     */
    protected boolean selected;    
    /**
     * Controla la Salida por consola del Resultado de los Procesos.
     */
    public static boolean print;
    
    /**
     * Mapa Utilitario de Intercambio de Objetos. 
     */
    protected HashMap<String, Object> objSwapValues;
    
    static{
        print = false;
    }
       
    /**
     * Constructor por Defecto.     
     */
    public ObjectBase() {
        id = -1;                
        objSwapValues = new HashMap<String, Object>();
        //
        // Creating a random UUID (Universally unique identifier).
        //        
        uuidObj = Utileria.getStringSerialUUID();
        if(print)System.out.println(uuidObj);
    } 

    /**
     * Constructor por Defecto.
     * @param id Propiedad utilizada para identificar el indice dentro de los archivos de
     * propiedades.
     */
    public ObjectBase(int id) {
        this.id = id;
        objSwapValues = new HashMap<String, Object>();
        //
        // Creating a random UUID (Universally unique identifier).
        //        
        uuidObj = Utileria.getStringSerialUUID();
        if(print)System.out.println(uuidObj);
    }

    /**
     * Devuelve el Indice de definición del Archivo de Propiedades.
     * @return Indice de definición del Archivo de Propiedades.
     */
    public int getId() {
        return id;
    }

    /**
     * Establece el Indice de definición del Archivo de Propiedades.
     * @param id Indice de definición del Archivo de Propiedades.
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * Devuelve el Indice de Idenficación del Objeto.
     * @return Indice de Idenficación del Objeto
     */
    public int getIdClase() {
        return idClase;
    }

    /**
     * Establece el Indice de Idenficación del Objeto.
     * @param idClase Indice de Idenficación del Objeto
     */
    public void setIdClase(int idClase) {
        this.idClase = idClase;
    }  
    
    /**
     * Devuelve el Estado que determina si el objeto ha sido seleccionado en un 
     * contenedor gráfico.
     * @return Estado que determina si el objeto ha sido seleccionado en un 
     * contenedor gráfico.
     */
    public boolean isSelected(){
        return selected;
    }
    
    /**
     * Establece el Estado que determina si el objeto ha sido seleccionado en un 
     * contenedor gráfico.
     * @param selected Estado que determina si el objeto ha sido seleccionado en un 
     * contenedor gráfico.
     */
    public void setSelected(boolean selected){
        this.selected = selected;
    }
    
    
    @Override
    public int compareTo(Object o) {
        try{
            ObjectBase obj = (ObjectBase) o;
            if(this.id > obj.id) {
                return 1;
            }
            else if(this.id < obj.id) {
                return -1;
            }
            else {
                return 0;
            }
        }catch(java.lang.NullPointerException ex){}
        return -1;
    }

    @Override
    @SuppressWarnings("empty-statement")
    protected Object clone() {
        ObjectBase objClon;
        try {
            //----------------------------------------------------------
            //Primero se Clona la Referencia Local
            //----------------------------------------------------------
            objClon = (ObjectBase) super.clone();
            //----------------------------------------------------------
            //Ahora se hace la Clonación Profunda
            //----------------------------------------------------------
            ((ObjectBase)objClon).uuidObj = Utileria.getStringSerialUUID();;        
            return objClon;
        } catch (CloneNotSupportedException ex) {
            Logger.getLogger(ObjectBase.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    /**
     * Agrega un Objeto al Mapa de Intercambio.
     * @param key   Llave de Identificación del Objeto,
     * @param value Objeto que se incluirá en el mapa de intercambio.
     */
    public void addSwap(String key, Object value){
        this.objSwapValues.put(key, value);
    }

    /**
     * Devuelve la instancia del mapa del intercambio.
     * @return instancia del mapa del intercambio.
     */
    public HashMap<String, Object> getObjSwapValues() {
        return objSwapValues;
    }
    
    /**
     * Evalua la existencia de una Llave de identificación en el mapa de intercambio.
     * @param key Llave de Identificación del Objeto,
     * @return boolean que determina la existencia de una Llave de identificación en el mapa de intercambio.
     */
    public boolean isSwapKey(String key){
        return objSwapValues.containsKey(key);        
    }
    
    /**
     * Evalua la existencia de un Objeto en el mapa de intercambio.
     * @param value Objeto.
     * @return boolean que determina la existencia de un Objeto en el mapa de intercambio.
     */
    public boolean isSwapValue(Object value){
        return objSwapValues.containsValue(value);        
    }    
}
